package com.spzx.common.rabbit.config;

import com.spzx.common.rabbit.entity.GuiguCorrelationData;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class SpzxRabbitTemplateConfiguration implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    RedisTemplate redisTemplate;

    @PostConstruct
    public void init(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if(ack){
            log.info("消息发送成功" + correlationData);
        }else {
            //重新发送消息，最多重试3次
            log.info("消息发送失败" + cause);
            GuiguCorrelationData guiguCorrelationData = (GuiguCorrelationData)correlationData;
            retry(guiguCorrelationData);
        }
    }

    private void retry(GuiguCorrelationData guiguCorrelationData) {
        int retryCount = guiguCorrelationData.getRetryCount();
        String exchange = guiguCorrelationData.getExchange();
        Object message = guiguCorrelationData.getMessage();
        String routingKey = guiguCorrelationData.getRoutingKey();
        if(retryCount < 3){
            //重新发送
            retryCount++;
            guiguCorrelationData.setRetryCount(retryCount);
            rabbitTemplate.convertAndSend(exchange, routingKey, message, guiguCorrelationData);
            redisTemplate.opsForValue().set(guiguCorrelationData.getId(), guiguCorrelationData);
            log.info("当前第" + retryCount + "次重发");
        }else {
            log.info("重发次数用尽");
        }

    }

    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        log.info("消息投递失败" + returnedMessage.getMessage()
                + "\nreplyCode" + returnedMessage.getReplyCode()
                + "\nreplyText" + returnedMessage.getReplyText()
                + "\nexchange" + returnedMessage.getExchange()
                + "\nroutingKey" + returnedMessage.getRoutingKey());


        String id = (String)returnedMessage.getMessage().getMessageProperties().getHeader("spring_returned_message_correlation");

        GuiguCorrelationData guiguCorrelationData = (GuiguCorrelationData)redisTemplate.opsForValue().get(id);
        if(guiguCorrelationData != null){
            retry(guiguCorrelationData);
        }
    }
}
